package com.logic.landseaserver.models.authcode.service;

import com.logic.common.exception.BusinessException;
import com.logic.common.security.SecurityUtils;
import com.logic.landseaserver.common.LandeaConstants;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.enums.BillTypeEnum;
import com.logic.landseaserver.common.enums.DepositEnum;
import com.logic.landseaserver.domain.CoupUsedRecord;
import com.logic.landseaserver.models.authcode.bean.AddCouponUesd;
import com.logic.landseaserver.models.authcode.bean.UsedAuthCode;
import com.logic.landseaserver.persistence.read.CoupUsedRecordReadMapper;
import com.logic.landseaserver.persistence.read.CouponReadMapper;
import com.logic.landseaserver.persistence.write.CoupUsedRecordWriteMapper;
import com.logic.landseaserver.ws.dto.QueryCouponUesdDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Junny on 2017/10/16.
 * 授权码使用service
 */
@Service
public class CouponUsedService {
    private static final Logger LOGGER = LoggerFactory.getLogger(CouponUsedService.class);

    @Autowired
    private CouponReadMapper couponReadMapper;

    @Autowired
    private CoupUsedRecordWriteMapper coupUsedRecordWriteMapper;

    @Autowired
    private CoupUsedRecordReadMapper coupUsedRecordReadMapper;

    /**
     * 使用的时候校验授权码是否可以使用
     * @param mainType 使用场景
     * @param usedUserId 使用人
     * @param authCodes 使用的授权码
     */
    public void checkUesdAuthCode(String mainType,Integer usedUserId, List<UsedAuthCode> authCodes) throws BusinessException {
        if(authCodes==null){
            return;
        }
        //查询授权码当前使用数量
        List<Integer> ids = new ArrayList<>();
        Set<String> typeSet = new HashSet<String>(); //费项
        for(UsedAuthCode code: authCodes){
            ids.add(code.getId());
            typeSet.add(code.getAuthFee());
        }
        HashMap<String,Object> map = new HashMap<>();

        if(ids.size()>0){
            map.put("ids",ids);
        }
        map.put("userId",usedUserId);
        // 查询个人/通用可使用的
        List<QueryCouponUesdDTO> personalCouponList = couponReadMapper.queryUesdCoupon(map);
        if(personalCouponList!=null){
            for(QueryCouponUesdDTO dto:personalCouponList){
                if(dto.getDeleted()){
                    throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_STATUS_ERROR.getDesc(),dto.getAuthCode()));
                }

                if(dto.getSelf()==false){
                    throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_NOUESD_ERROR.getDesc(),dto.getAuthCode()));
                }
                Optional<UsedAuthCode> uesdCode = authCodes.stream().filter(e -> e.getId().equals(dto.getId())).findFirst();
               if(uesdCode.isPresent()){
                   if(uesdCode.get().getCouponUesdId()==null){
                       if(dto.getAppropriateType().equals(LandeaConstants.AppropriateType.COMMON)){//通用
                           if(dto.getUesdCount()>=dto.getPutOnAmount()){
                               throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_NOCOUNT_ERROR.getDesc(),dto.getAuthCode()));
                           }
                       }else{//个人
                           if(dto.getUesdCount()!=0){
                               throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_NOCOUNT_ERROR.getDesc(),dto.getAuthCode()));
                           }
                       }
                   }
               }
               /* if(dto.getSelf()==false){
                    throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_NOUESD_ERROR.getDesc(),dto.getAuthCode()));
                }*/
                if(dto.getQuota()<0){
                    throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_MONRY_DISCOUNT_ERROR.getDesc(),dto.getAuthCode()));
                }
                //判断使用金额是否大于授权码价格

                if(dto.getMoneyType().equals(LandeaConstants.MoneyType.DISCOUNT)){
                    if(uesdCode.get().getQuota().compareTo(dto.getQuota())<0){
                        throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_MONRY_ERROR.getDesc(),dto.getAuthCode()));
                    }
                }else{//如果是金额
                    if(uesdCode.get().getQuota().compareTo(dto.getQuota())>0){
                        throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_MONRY_ERROR.getDesc(),dto.getAuthCode()));
                    }
                }

            }
            //个人授权码同一费项只允许使用一个
            List<UsedAuthCode> uesdCodes = authCodes.stream().filter(e -> e.getAppropriateType().equals(LandeaConstants.AppropriateType.PERSION)).collect(Collectors.toList());
            if(uesdCodes!=null){
                Set grTypeSet = new HashSet<>();
                uesdCodes.forEach(e->grTypeSet.add(e.getAuthFee()));
                if(grTypeSet.size()!=uesdCodes.size()){
                    throw new BusinessException(LandseaErrorMessageEnum.AUTHCODE_USED_GR_TYPE_ERROR.getDesc());
                }
            }
            for(String authType:typeSet){
                long codeDiscount = authCodes.stream().filter(e -> e.getAuthFee().equals(authType) && e.getMoneyType().equals(LandeaConstants.MoneyType.DISCOUNT)).count();
                //同一费项，折扣类的授权码只能使用一个
                if(codeDiscount>1){
                    throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_DISCOUNTTPYE_ERROR.getDesc(),authType));
                }
                List<UsedAuthCode> codeMoneyAndDis = authCodes.stream().filter(e -> e.getAuthFee().equals(authType) &&
                        (e.getMoneyType().equals(LandeaConstants.MoneyType.MONEY)|| e.getMoneyType().equals(LandeaConstants.MoneyType.DISCOUNT))).collect(Collectors.toList());
                //同一费项，不能既有折扣又有优惠
                if(codeMoneyAndDis!=null){
                    Set<String> codeMds = new HashSet<>();
                    codeMoneyAndDis.forEach(e->codeMds.add(e.getAuthFee()));
                    if(codeMds.size()>1){
                        throw new BusinessException(String.format(LandseaErrorMessageEnum.AUTHCODE_USED_TPYE_ERROR.getDesc(),authType));
                    }
                }
                //如果是签约和预定时 则需要判断是否突破底价
                if(mainType.equals(LandeaConstants.QueryUesdCodeType.CONTRACT) || mainType.equals(LandeaConstants.QueryUesdCodeType.DEPOSIT)){

                }
            }
        }
    }

    public void insertUesdList(AddCouponUesd couponUesds){
        List<CoupUsedRecord> codeRecords = new ArrayList<>();
        for(UsedAuthCode usedCode:couponUesds.getAuthCodes()){
            //预定转签约带过来的授权码信息
            if(couponUesds.getMainType().equals(LandeaConstants.QueryUesdCodeType.CONTRACT) && usedCode.getOriginalId()!=null
                    && !usedCode.getAuthFee().equals(BillTypeEnum.CTBI18.getCode())){
                CoupUsedRecord record = new CoupUsedRecord();
                record.setScenarioType(couponUesds.getMainType());
                record.setMainId(couponUesds.getMainId());
                record.setId(usedCode.getCouponUesdId());
                record.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
                coupUsedRecordWriteMapper.updateByPrimaryKeySelective(record);
            }else{
                CoupUsedRecord record = new CoupUsedRecord();
                record.setScenarioType(couponUesds.getMainType());
                record.setMainId(couponUesds.getMainId());
                record.setCouponId(usedCode.getId());
                record.setUserId(couponUesds.getUserId());
                record.setProjectId(couponUesds.getPrjId());
                record.setAuthFee(usedCode.getAuthFee());
                record.setMoneyType(usedCode.getMoneyType());
                record.setRealQuota(usedCode.getQuota());
                record.setUesdStatus(DepositEnum._DS2.getCode());
                if(couponUesds.getMainType().equals(LandeaConstants.QueryUesdCodeType.DEPOSIT)){
                    record.setOriginalId(couponUesds.getMainId());//只有预定才有
                }
                record.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
                codeRecords.add(record);
            }
        }
        if(codeRecords.size()>0){
            coupUsedRecordWriteMapper.insertList(codeRecords);
        }
    }

    public void deleteCouponUesd(Integer mainId,String mainType){
        if(mainType.equals(LandeaConstants.QueryUesdCodeType.DEPOSIT) || mainType.equals(LandeaConstants.QueryUesdCodeType.CONTRACT)){
            //删除预定相关的授权码使用   //删除合同相关的授权码使用
            coupUsedRecordWriteMapper.deleteByMIdAndType(mainId,mainType);
        }else if(mainType.equals(LandeaConstants.QueryUesdCodeType.MONTHBILL)){

        }else if(mainType.equals(LandeaConstants.QueryUesdCodeType.OFFRENT)){
            coupUsedRecordWriteMapper.deleteByMIdAndType(mainId,mainType);
        }
    }

    public void removeCouponUesd(Integer mainId,String mainType){
        coupUsedRecordWriteMapper.removeByMIdAndType(mainId,mainType);
    }

    public List<UsedAuthCode> queryCouponUesd(HashMap map){
        return coupUsedRecordReadMapper.queryUsedAuthCode(map);
    }

    public  List<QueryCouponUesdDTO> querypPersonalCouponList(HashMap map){
        return coupUsedRecordReadMapper.queryUsedRecord(map);
    }

    public void deleteCouponUesdById(Integer id){
        coupUsedRecordWriteMapper.deleteByPrimaryKey(id);
    }

    public void removeCouponUesdSvDeposit(Integer mainId,String mainType){
        coupUsedRecordWriteMapper.removeCouponUesdSvDeposit(mainId,mainType);
    }
}
